#include "stdafx.h"
#include "iodevice.h"
#include "workthread.h"

namespace rco {
	
bool RcoWorkThread::IsWorking() const
{
	return m_iTaskId != 0;
}

RcoWorkThread::RcoWorkThread()
	: QThread(nullptr)
{
	m_pIODevice = nullptr;
	m_iTaskId = 0;
	m_cmdHandler.Init();
}

bool RcoWorkThread::Execute(const RcoCommandHead& rcoCmdHead, const RcoBuffer& bytes, int iTaskId)
{
	if (IsWorking() || !m_pIODevice)
		return false;
	
	m_rcoCmdHead = rcoCmdHead;
	m_iTaskId = iTaskId;

	m_rcoCmdHead.result = m_cmdHandler.Do(&m_rcoCmdHead, &bytes, m_pIODevice, &m_buf); // m_buf not init

	m_pIODevice->GetKey();
	if (m_rcoCmdHead.result32 & RCO_CR_NOT_SEND)
		m_pIODevice->Write(&m_rcoCmdHead, nullptr);			
	else
		m_pIODevice->Write(&m_rcoCmdHead, &m_buf);
	m_pIODevice->ReleaseKey();

	m_iTaskId = 0;
	emit TaskCompleted(this, &m_rcoCmdHead, &m_buf);

	return true;
}

void RcoWorkThread::run()
{
	// Enter MESSAGE LOOP until exit is called
	exec();
}

bool RcoWorkThread::SetIODevice(RcoIODevice* pIODevice)
{
	if (IsWorking())
		return false;

	m_pIODevice = pIODevice;
	return true;
}

RcoIODevice* RcoWorkThread::GetIODevice()
{
	return m_pIODevice;
}

const RcoIODevice* RcoWorkThread::GetIODevice() const
{
	return m_pIODevice;
}

void RcoWorkThread::customEvent(QEvent * event)
{
	switch(event->type())
	{
	case RcoWorkThreadData::RcoData:
		{
			RcoWorkThreadData* wkEvent = static_cast<RcoWorkThreadData*>(event);
			Execute(wkEvent->rcoCmdHread, wkEvent->bytes, wkEvent->iTaskId);
		}
		break;
	default:
		QThread::customEvent(event);
	}
}

RcoWorkThread::~RcoWorkThread()
{
}

void* RcoWorkThread::operator new(quint32 size)
{
	RcoWorkThread* p = ::new RcoWorkThread;
	QObject::connect(p, SIGNAL(finished()), p, SLOT(deleteLater()));
	return p;
}

void RcoWorkThread::Suidside()
{
	delete this;
}

RcoWorkThreadData::RcoWorkThreadData()
	: QEvent((QEvent::Type)RcoData)
{
	iTaskId = 0;
}

}